/*     */ package com.zimbra.cs.account;
/*     */ 
/*     */ import com.google.common.collect.Lists;
/*     */ import com.google.common.collect.Ordering;
/*     */ import com.google.common.collect.TreeMultimap;
/*     */ import com.zimbra.client.ToZJSONObject;
/*     */ import com.zimbra.client.ZJSONObject;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.DateUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import java.text.CollationKey;
/*     */ import java.text.Collator;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Arrays;
/*     */ import java.util.Collection;
/*     */ import java.util.Comparator;
/*     */ import java.util.Date;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Locale;
/*     */ import java.util.Map;
/*     */ import java.util.Map.Entry;
/*     */ import java.util.Set;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import org.json.JSONException;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public abstract class Entry
/*     */   implements ToZJSONObject
/*     */ {
/*     */   private Map<String, Object> mAttrs;
/*     */   private Map<String, Object> mDefaults;
/*     */   private Map<String, Object> mSecondaryDefaults;
/*     */   private Map<String, Object> overrideDefaults;
/*     */   private Map<String, Object> mData;
/*     */   private Map<String, Set<String>> mMultiAttrSetCache;
/*     */   private Map<String, Set<byte[]>> mMultiBinaryAttrSetCache;
/*     */   private Locale mLocale;
/*     */   private final Provisioning mProvisioning;
/*     */   private AttributeManager mAttrMgr;
/*     */   
/*     */   public static enum EntryType
/*     */   {
/*  53 */     ENTRY, 
/*  54 */     ACCOUNT, 
/*  55 */     ALIAS, 
/*  56 */     CALRESOURCE, 
/*  57 */     COS, 
/*  58 */     DATASOURCE, 
/*  59 */     DISTRIBUTIONLIST, 
/*  60 */     DOMAIN, 
/*  61 */     DYNAMICGROUP, 
/*  62 */     DYNAMICGROUP_DYNAMIC_UNIT, 
/*  63 */     DYNAMICGROUP_STATIC_UNIT, 
/*  64 */     GLOBALCONFIG, 
/*  65 */     GLOBALGRANT, 
/*  66 */     IDENTITY, 
/*  67 */     MIMETYPE, 
/*  68 */     SERVER, 
/*  69 */     ALWAYSONCLUSTER, 
/*  70 */     UCSERVICE, 
/*  71 */     SIGNATURE, 
/*  72 */     XMPPCOMPONENT, 
/*  73 */     ZIMLET;
/*     */     
/*     */     private EntryType() {}
/*  76 */     public String getName() { return name(); }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*  91 */   protected static String[] sEmptyMulti = new String[0];
/*  92 */   protected static List<byte[]> sEmptyListMulti = new ArrayList();
/*     */   
/*     */   public EntryType getEntryType() {
/*  95 */     return EntryType.ENTRY;
/*     */   }
/*     */   
/*     */   protected Entry(Map<String, Object> attrs, Map<String, Object> defaults, Provisioning provisioning)
/*     */   {
/* 100 */     this.mProvisioning = provisioning;
/* 101 */     this.mAttrs = attrs;
/* 102 */     this.mDefaults = defaults;
/* 103 */     setAttributeManager();
/*     */   }
/*     */   
/*     */   protected Entry(Map<String, Object> attrs, Map<String, Object> defaults, Map<String, Object> secondaryDefaults, Provisioning provisioning)
/*     */   {
/* 108 */     this.mProvisioning = provisioning;
/* 109 */     this.mAttrs = attrs;
/* 110 */     this.mDefaults = defaults;
/* 111 */     this.mSecondaryDefaults = secondaryDefaults;
/* 112 */     setAttributeManager();
/*     */   }
/*     */   
/*     */   protected Entry(Map<String, Object> attrs, Map<String, Object> defaults, Map<String, Object> secondaryDefaults, Map<String, Object> overrideDefaults, Provisioning provisioning)
/*     */   {
/* 117 */     this.mProvisioning = provisioning;
/* 118 */     this.mAttrs = attrs;
/* 119 */     this.mDefaults = defaults;
/* 120 */     this.mSecondaryDefaults = secondaryDefaults;
/* 121 */     this.overrideDefaults = overrideDefaults;
/* 122 */     setAttributeManager();
/*     */   }
/*     */   
/*     */   private void setAttributeManager() {
/*     */     try {
/* 127 */       this.mAttrMgr = AttributeManager.getInstance();
/*     */     } catch (ServiceException se) {
/* 129 */       ZimbraLog.account.warn("failed to get AttributeManager instance", se);
/*     */     }
/*     */   }
/*     */   
/*     */   private AttributeManager getAttributeManager() {
/* 134 */     return this.mAttrMgr;
/*     */   }
/*     */   
/*     */   public Provisioning getProvisioning() {
/* 138 */     return this.mProvisioning;
/*     */   }
/*     */   
/*     */ 
/*     */   public String getLabel()
/*     */   {
/* 144 */     return "unknown";
/*     */   }
/*     */   
/*     */   public synchronized void setAttrs(Map<String, Object> attrs, Map<String, Object> defaults, Map<String, Object> secondaryDefaults, Map<String, Object> overrideDefaults)
/*     */   {
/* 149 */     this.mAttrs = attrs;
/* 150 */     this.mDefaults = defaults;
/* 151 */     this.mSecondaryDefaults = secondaryDefaults;
/* 152 */     this.overrideDefaults = overrideDefaults;
/* 153 */     resetData();
/*     */   }
/*     */   
/*     */   public synchronized void setAttrs(Map<String, Object> attrs) {
/* 157 */     this.mAttrs = attrs;
/* 158 */     resetData();
/*     */   }
/*     */   
/*     */   public synchronized void setDefaults(Map<String, Object> defaults) {
/* 162 */     this.mDefaults = defaults;
/* 163 */     resetData();
/*     */   }
/*     */   
/*     */   public synchronized void setDefaults(Map<String, Object> defaults, Map<String, Object> secondaryDefaults)
/*     */   {
/* 168 */     this.mDefaults = defaults;
/* 169 */     this.mSecondaryDefaults = secondaryDefaults;
/* 170 */     resetData();
/*     */   }
/*     */   
/*     */   public synchronized void setSecondaryDefaults(Map<String, Object> secondaryDefaults) {
/* 174 */     this.mSecondaryDefaults = secondaryDefaults;
/* 175 */     resetData();
/*     */   }
/*     */   
/*     */   public synchronized void setOverrideDefaults(Map<String, Object> overrideDefaults) {
/* 179 */     this.overrideDefaults = overrideDefaults;
/* 180 */     resetData();
/*     */   }
/*     */   
/*     */   protected synchronized void resetData()
/*     */   {
/* 185 */     if (this.mMultiAttrSetCache != null)
/* 186 */       this.mMultiAttrSetCache.clear();
/* 187 */     if (this.mData != null)
/* 188 */       this.mData.clear();
/* 189 */     this.mLocale = null;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private Object getObject(String name, boolean applyDefaults)
/*     */   {
/* 201 */     Object v = this.mAttrs.get(name);
/* 202 */     if (v != null) { return v;
/*     */     }
/* 204 */     v = getValueByRealAttrName(name, this.mAttrs);
/* 205 */     if (v != null) { return v;
/*     */     }
/* 207 */     if (!applyDefaults) {
/* 208 */       return null;
/*     */     }
/* 210 */     return getAttrDefault(name);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public Object getAttrDefault(String name)
/*     */   {
/* 217 */     if (this.overrideDefaults != null) {
/* 218 */       Object v = this.overrideDefaults.get(name);
/* 219 */       if (v != null) { return v;
/*     */       }
/* 221 */       v = getValueByRealAttrName(name, this.overrideDefaults);
/* 222 */       if (v != null) { return v;
/*     */       }
/*     */     }
/*     */     
/* 226 */     if (this.mDefaults != null) {
/* 227 */       Object v = this.mDefaults.get(name);
/* 228 */       if (v != null) { return v;
/*     */       }
/* 230 */       v = getValueByRealAttrName(name, this.mDefaults);
/* 231 */       if (v != null) { return v;
/*     */       }
/*     */     }
/*     */     
/* 235 */     if (this.mSecondaryDefaults != null) {
/* 236 */       Object v = this.mSecondaryDefaults.get(name);
/* 237 */       if (v != null) { return v;
/*     */       }
/* 239 */       v = getValueByRealAttrName(name, this.mSecondaryDefaults);
/* 240 */       if (v != null) { return v;
/*     */       }
/*     */     }
/* 243 */     return null;
/*     */   }
/*     */   
/*     */   private Object getValueByRealAttrName(String attrName, Map<String, Object> map)
/*     */   {
/* 248 */     AttributeManager attrMgr = getAttributeManager();
/* 249 */     if (attrMgr != null) {
/* 250 */       AttributeInfo ai = attrMgr.getAttributeInfo(attrName);
/* 251 */       if (ai != null)
/* 252 */         return map.get(ai.getName());
/*     */     }
/* 254 */     return null;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private Map<String, Object> toUnicode(Map<String, Object> attrs)
/*     */   {
/* 263 */     AttributeManager attrMgr = getAttributeManager();
/*     */     
/* 265 */     Set<String> keySet = new HashSet(attrs.keySet());
/* 266 */     for (String key : keySet) {
/* 267 */       AttributeManager.IDNType idnType = AttributeManager.idnType(attrMgr, key);
/* 268 */       if (idnType.isEmailOrIDN()) {
/* 269 */         Object value = attrs.get(key);
/* 270 */         if ((value instanceof String[])) {
/* 271 */           String[] sv = (String[])value;
/* 272 */           for (int i = 0; i < sv.length; i++) {
/* 273 */             sv[i] = IDNUtil.toUnicode(sv[i], idnType);
/*     */           }
/* 275 */         } else if ((value instanceof String)) {
/* 276 */           attrs.put(key, IDNUtil.toUnicode((String)value, idnType));
/*     */         }
/*     */       }
/*     */     }
/*     */     
/* 281 */     return attrs;
/*     */   }
/*     */   
/*     */   public String getAttr(String name) {
/* 285 */     return getAttr(name, true);
/*     */   }
/*     */   
/*     */   public String getAttr(String name, boolean applyDefaults) {
/* 289 */     Object v = getObject(name, applyDefaults);
/* 290 */     if ((v instanceof String))
/* 291 */       return (String)v;
/* 292 */     if ((v instanceof String[])) {
/* 293 */       String[] a = (String[])v;
/* 294 */       return a.length > 0 ? a[0] : null;
/*     */     }
/* 296 */     return null;
/*     */   }
/*     */   
/*     */   public String getAttr(String name, String defaultValue)
/*     */   {
/* 301 */     String v = getAttr(name);
/* 302 */     return v == null ? defaultValue : v;
/*     */   }
/*     */   
/*     */   protected Map<String, Object> getRawAttrs() {
/* 306 */     return this.mAttrs;
/*     */   }
/*     */   
/*     */   public Map<String, Object> getAttrs() {
/* 310 */     return getAttrs(true);
/*     */   }
/*     */   
/*     */   public Map<String, Object> getUnicodeAttrs() {
/* 314 */     Map<String, Object> attrs = getAttrs(true);
/* 315 */     return toUnicode(attrs);
/*     */   }
/*     */   
/*     */   public Map<String, Object> getAttrs(boolean applyDefaults) {
/* 319 */     if ((applyDefaults) && ((this.mDefaults != null) || (this.mSecondaryDefaults != null))) {
/* 320 */       Map<String, Object> attrs = new HashMap();
/*     */       
/* 322 */       if (this.mSecondaryDefaults != null) {
/* 323 */         attrs.putAll(this.mSecondaryDefaults);
/*     */       }
/*     */       
/* 326 */       if (this.mDefaults != null) {
/* 327 */         attrs.putAll(this.mDefaults);
/*     */       }
/*     */       
/* 330 */       attrs.putAll(this.mAttrs);
/*     */       
/*     */ 
/* 333 */       if (this.overrideDefaults != null) {
/* 334 */         attrs.putAll(this.overrideDefaults);
/*     */       }
/* 336 */       return attrs;
/*     */     }
/* 338 */     return this.mAttrs;
/*     */   }
/*     */   
/*     */   public Map<String, Object> getUnicodeAttrs(boolean applyDefaults)
/*     */   {
/* 343 */     Map<String, Object> attrs = getAttrs(applyDefaults);
/* 344 */     return toUnicode(attrs);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public boolean getBooleanAttr(String name, boolean defaultValue)
/*     */   {
/* 354 */     String v = getAttr(name);
/* 355 */     return v == null ? defaultValue : "TRUE".equals(v);
/*     */   }
/*     */   
/*     */   public byte[] getBinaryAttr(String name) {
/* 359 */     String v = getAttr(name);
/* 360 */     return v == null ? null : ByteUtil.decodeLDAPBase64(v);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public Date getGeneralizedTimeAttr(String name, Date defaultValue)
/*     */   {
/* 370 */     String v = getAttr(name);
/* 371 */     if (v == null)
/* 372 */       return defaultValue;
/* 373 */     Date d = DateUtil.parseGeneralizedTime(v);
/* 374 */     return d == null ? defaultValue : d;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public int getIntAttr(String name, int defaultValue)
/*     */   {
/* 384 */     String v = getAttr(name);
/*     */     try {
/* 386 */       return v == null ? defaultValue : Integer.parseInt(v);
/*     */     } catch (NumberFormatException e) {}
/* 388 */     return defaultValue;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public Locale getLocale()
/*     */     throws ServiceException
/*     */   {
/* 397 */     synchronized (this) {
/* 398 */       if (this.mLocale != null)
/* 399 */         return this.mLocale;
/*     */     }
/* 401 */     Locale lc = Provisioning.getInstance().getLocale(this);
/* 402 */     synchronized (this) {
/* 403 */       this.mLocale = lc;
/* 404 */       return this.mLocale;
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public long getLongAttr(String name, long defaultValue)
/*     */   {
/* 415 */     String v = getAttr(name);
/*     */     try {
/* 417 */       return v == null ? defaultValue : Long.parseLong(v);
/*     */     } catch (NumberFormatException e) {}
/* 419 */     return defaultValue;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public String[] getMultiAttr(String name)
/*     */   {
/* 428 */     return getMultiAttr(name, true);
/*     */   }
/*     */   
/*     */   public List<byte[]> getMultiBinaryAttr(String name) {
/* 432 */     return getMultiBinaryAttr(name, true);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public String[] getUnicodeMultiAttr(String name)
/*     */   {
/* 440 */     String[] values = getMultiAttr(name, true);
/*     */     
/* 442 */     AttributeManager attrMgr = getAttributeManager();
/* 443 */     AttributeManager.IDNType idnType = AttributeManager.idnType(attrMgr, name);
/* 444 */     if ((idnType.isEmailOrIDN()) && (values != null)) {
/* 445 */       String[] unicodeValues = new String[values.length];
/* 446 */       for (int i = 0; i < values.length; i++)
/* 447 */         unicodeValues[i] = IDNUtil.toUnicode(values[i], idnType);
/* 448 */       return unicodeValues;
/*     */     }
/* 450 */     return values;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public String[] getMultiAttr(String name, boolean applyDefaults)
/*     */   {
/* 458 */     Object v = getObject(name, applyDefaults);
/* 459 */     if ((v instanceof String))
/* 460 */       return new String[] { (String)v };
/* 461 */     if ((v instanceof String[])) {
/* 462 */       return (String[])v;
/*     */     }
/* 464 */     return sEmptyMulti;
/*     */   }
/*     */   
/*     */   public List<byte[]> getMultiBinaryAttr(String name, boolean applyDefaults)
/*     */   {
/* 469 */     String[] values = getMultiAttr(name, applyDefaults);
/* 470 */     if (values.length > 0) {
/* 471 */       List<byte[]> list = new ArrayList();
/* 472 */       for (String value : values) {
/* 473 */         list.add(ByteUtil.decodeLDAPBase64(value));
/*     */       }
/* 475 */       return list;
/*     */     }
/* 477 */     return sEmptyListMulti;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public Set<String> getMultiAttrSet(String name)
/*     */   {
/* 486 */     if (this.mMultiAttrSetCache == null)
/* 487 */       this.mMultiAttrSetCache = new HashMap();
/* 488 */     Set<String> result = (Set)this.mMultiAttrSetCache.get(name);
/* 489 */     if (result == null) {
/* 490 */       result = new HashSet(Arrays.asList(getMultiAttr(name)));
/* 491 */       this.mMultiAttrSetCache.put(name, result);
/*     */     }
/* 493 */     return result;
/*     */   }
/*     */   
/*     */   public Set<byte[]> getMultiBinaryAttrSet(String name)
/*     */   {
/* 498 */     if (this.mMultiBinaryAttrSetCache == null)
/* 499 */       this.mMultiBinaryAttrSetCache = new HashMap();
/* 500 */     Set<byte[]> result = (Set)this.mMultiBinaryAttrSetCache.get(name);
/* 501 */     if (result == null) {
/* 502 */       result = new HashSet(getMultiBinaryAttr(name));
/* 503 */       this.mMultiBinaryAttrSetCache.put(name, result);
/*     */     }
/* 505 */     return result;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public long getTimeInterval(String name, long defaultValue)
/*     */   {
/* 520 */     return DateUtil.getTimeInterval(getAttr(name), defaultValue);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public long getTimeIntervalSecs(String name, long defaultValue)
/*     */   {
/* 535 */     return DateUtil.getTimeIntervalSecs(getAttr(name), defaultValue);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public synchronized void setCachedData(String key, Object value)
/*     */   {
/* 546 */     if (this.mData == null)
/* 547 */       this.mData = new HashMap();
/* 548 */     this.mData.put(key, value);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void setCachedData(EntryCacheDataKey key, Object value)
/*     */   {
/* 562 */     setCachedData(key.getKeyName(), value);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public synchronized Object getCachedData(String key)
/*     */   {
/* 571 */     if (this.mData == null) {
/* 572 */       return null;
/*     */     }
/* 574 */     return this.mData.get(key);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public Object getCachedData(EntryCacheDataKey key)
/*     */   {
/* 587 */     return getCachedData(key.getKeyName());
/*     */   }
/*     */   
/*     */   public synchronized void removeCachedData(EntryCacheDataKey key) {
/* 591 */     if (this.mData == null) {
/* 592 */       return;
/*     */     }
/* 594 */     this.mData.remove(key.getKeyName());
/*     */   }
/*     */   
/*     */   protected void getDefaults(AttributeFlag flag, Map<String, Object> defaults) throws ServiceException
/*     */   {
/* 599 */     defaults.clear();
/* 600 */     Set<String> attrs = AttributeManager.getInstance().getAttrsWithFlag(flag);
/* 601 */     for (String a : attrs) {
/* 602 */       Object obj = getObject(a, true);
/* 603 */       if (obj != null) { defaults.put(a, obj);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */   public synchronized String toString()
/*     */   {
/* 610 */     return String.format("[%s]", new Object[] { getClass().getName() });
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public ZJSONObject toZJSONObject()
/*     */     throws JSONException
/*     */   {
/* 623 */     return toZJSONObject(null, true);
/*     */   }
/*     */   
/* 626 */   static Pattern regex = Pattern.compile("^/(.*)/(i)?$");
/*     */   
/*     */   public ZJSONObject toZJSONObject(String filter, boolean applyDefaults) throws JSONException {
/* 629 */     Map<String, Object> attrs = getAttrs(applyDefaults);
/*     */     
/* 631 */     if ((this instanceof NamedEntry)) {
/* 632 */       NamedEntry ne = (NamedEntry)this;
/* 633 */       attrs.put("id", ne.getId());
/* 634 */       attrs.put("name", ne.getName());
/*     */     }
/*     */     
/* 637 */     Pattern pattern = null;
/* 638 */     if (filter != null) {
/* 639 */       Matcher rm = regex.matcher(filter);
/* 640 */       if (rm.matches()) {
/* 641 */         pattern = Pattern.compile(rm.group(1), "i".equals(rm.group(2)) ? 2 : 0);
/*     */       } else {
/* 643 */         filter = filter.toLowerCase();
/*     */       }
/*     */     }
/* 646 */     ZJSONObject zj = new ZJSONObject();
/* 647 */     for (Map.Entry<String, Object> entry : attrs.entrySet()) {
/* 648 */       if (pattern != null ? 
/* 649 */         pattern.matcher((CharSequence)entry.getKey()).find() : 
/* 650 */         (filter == null) || 
/* 651 */         (((String)entry.getKey()).toLowerCase().contains(filter)))
/*     */       {
/* 653 */         Object o = entry.getValue();
/* 654 */         if ((o instanceof String)) {
/* 655 */           zj.put((String)entry.getKey(), (String)o);
/* 656 */         } else if ((o instanceof String[]))
/* 657 */           zj.put((String)entry.getKey(), (String[])o);
/*     */       }
/*     */     }
/* 660 */     return zj;
/*     */   }
/*     */   
/*     */   public String dump() throws JSONException {
/* 664 */     return dump(null, true);
/*     */   }
/*     */   
/*     */   public String dump(String filter) throws JSONException {
/* 668 */     return dump(filter, true);
/*     */   }
/*     */   
/*     */   public String dump(String filter, boolean applyDefaults) throws JSONException {
/* 672 */     return toZJSONObject(filter, applyDefaults).toString();
/*     */   }
/*     */   
/*     */   private static final class SortByLabelAsc implements Comparator<Entry>
/*     */   {
/*     */     public int compare(Entry m1, Entry m2) {
/* 678 */       return m1.getLabel().compareTo(m2.getLabel());
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static List<Entry> sortByDisplayName(Collection<? extends Entry> entries, Locale locale)
/*     */   {
/* 688 */     List<Entry> sorted = Lists.newArrayList();
/*     */     
/*     */ 
/* 691 */     if (entries.size() <= 1) {
/* 692 */       sorted.addAll(entries);
/*     */     } else {
/* 694 */       Collator collator = Collator.getInstance(locale);
/*     */       
/* 696 */       TreeMultimap<CollationKey, Entry> map = TreeMultimap.create(Ordering.natural(), new SortByLabelAsc(null));
/*     */       
/*     */ 
/* 699 */       for (Entry entry : entries) {
/* 700 */         String key = entry.getAttr("displayName");
/* 701 */         if (key == null) {
/* 702 */           key = entry.getLabel();
/*     */         }
/* 704 */         CollationKey collationKey = collator.getCollationKey(key);
/*     */         
/* 706 */         map.put(collationKey, entry);
/*     */       }
/*     */       
/* 709 */       sorted.addAll(map.values());
/*     */     }
/* 711 */     return sorted;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/Entry.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */